package red;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Vector;

import org.omg.CORBA.Request;

import arjuna.JavaSim.Simulation.RestartException;
import arjuna.JavaSim.Simulation.Scheduler;
import arjuna.JavaSim.Simulation.SimulationException;
import arjuna.JavaSim.Simulation.SimulationProcess;
import arjuna.JavaSim.Statistics.Mean;
import arjuna.JavaSim.Statistics.TimeVariance;

public class MachineShop extends SimulationProcess {
	public static Machine servidor[];
	public static long TotalJobs = 0;
	public static long ErasedJobs = 0;
	public static int tiempoSimulacion = 10000;
	public static double TotalResponseTime=0.0;
	public static int semilla;
	private static int muti=3;
	public static final int TRANSITORIO=50;
	public static Mean meanDelay = new Mean ();
	public static TimeVariance meanQueue = new TimeVariance ();
	private PrintWriter salida;
	private static String ficheroSalida;
	public static int nodos;
	public static double AnchoBanda;
	public static double peticiones;
	public static double tiempoServicio;
	
	public MachineShop (double requests, int nNodos,double anchoBanda, int tSimulacion, int sem, 
			String fSalida) 
	{

		funcionSemilla(requests, nNodos, anchoBanda, tSimulacion, sem, fSalida);
		
		System.out.println ("Numero de Nodos: " + nodos);
		System.out.println ("Numero de peticiones por segundo: " + peticiones);
		System.out.println ("Tiempo de servicio: " + tiempoServicio);
		System.out.println ("Semilla: " + semilla);
		System.out.println ("El ancho de banda es : "+AnchoBanda);
		System.out.println ("Fichero de salida: " + fSalida);
		try {
			salida = new PrintWriter(ficheroSalida);
		}
		catch (IOException e) { System.out.println ("Error abriendo fichero de salida"); }
	}

	
	public void run () {
		
		try {
			Arrivals A = new Arrivals(peticiones,semilla,nodos);
			
			servidor = new Machine[nodos];

			for(int nNodos=0; nNodos<nodos ; nNodos++)
			{
				servidor[nNodos] = new Machine(tiempoSimulacion,nNodos);
			}

			A.Activate();

			Scheduler.startSimulation();

			while (ErasedJobs < tiempoSimulacion) {
				System.out.println(ErasedJobs);
				salida.println (ErasedJobs + "" + meanDelay.mean () + " " + meanQueue.mean ());
				Hold(1000);
				//System.out.println("Activando");
			}
			salida.close ();

			Scheduler.stopSimulation();

			A.terminate();

			for(int nServidor=0; nServidor<nodos ; nServidor++)
			{
				servidor[nServidor].terminate();
			}
			long procesados=0;
			for(int nServidor=0; nServidor<nodos ; nServidor++)
			{
				procesados+=servidor[nServidor].ProcessedJobs();
			}

			System.out.println ("Trabajos procesados: " + procesados);	 	 
			System.out.println ("N�mero total de trabajos presentes: "+TotalJobs);
			System.out.println ("Tiempo medio de respuesta: "+meanDelay.mean());
			System.out.println ("N�mero de clientes en cola "+meanQueue.mean ());

			// el cerrojo se hereda del paquete de simulacion
			// se declara en la simulationProcess.java -> public Object cerrojo = new Object();
			synchronized(cerrojo) { //modificado
				cerrojo.notify(); // Hago que se despierte el Main
			}

		}
		catch (SimulationException e) {
		}
		catch (RestartException e) {
		}
		System.out.println("cont vale" + peticiones);
	}

	private void funcionSemilla(double requests, int nNodos,double anchoBanda, int tSimulacion, int sem, 
			String fSalida)
			{
			ficheroSalida = fSalida;
			semilla = sem;
			if(sem==1)
			{
			nodos=nNodos;
			peticiones=requests;
			AnchoBanda=anchoBanda*muti;
			tiempoSimulacion = tSimulacion;
			tiempoServicio=1/(AnchoBanda*10);	
			}

			else
			{
			//numero de nodos
			if(sem<10)
			{
			nodos=10;
			}
			else
			{
			if(sem<20)
			{
			nodos=15;
			}
			else
			{
			nodos=20;
			}
			}

			switch (sem) {
			case 0:	peticiones=5; break;
			case 1:	peticiones=5; break;
			case 2:	peticiones=5;break;
			case 3:	peticiones=10;break;
			case 4:	peticiones=10;break;
			case 5:	peticiones=10;break;
			case 6:	peticiones=15;break;
			case 7:	peticiones=15;break;
			case 8:	peticiones=15;break;
			case 9:	peticiones=5;break;
			case 10:	peticiones=5;break;
			case 11:	peticiones=5;break;
			case 12:	peticiones=10;break;
			case 13:	peticiones=10;break;
			case 14:	peticiones=10;break;
			case 15:	peticiones=15;break;
			case 16:	peticiones=15;break;
			case 17:	peticiones=15;break;
			case 18:	peticiones=5;break;
			case 19:	peticiones=5;break;
			case 20:	peticiones=5;break;
			case 21:	peticiones=10;break;
			case 22:	peticiones=10;break;
			case 23:	peticiones=10;break;
			case 24:	peticiones=15;break;
			case 25:	peticiones=15;break;
			case 26:	peticiones=15;break;
			}
			switch (sem) {
			case 0:	AnchoBanda=1; break;
			case 1:	AnchoBanda=2; break;
			case 2:	AnchoBanda=3;break;
			case 3:	AnchoBanda=1;break;
			case 4:	AnchoBanda=2;break;
			case 5:	AnchoBanda=3;break;
			case 6:	AnchoBanda=1;break;
			case 7:	AnchoBanda=2;break;
			case 8:	AnchoBanda=3;break;
			case 9:	AnchoBanda=1;break;
			case 10:	AnchoBanda=2;break;
			case 11:	AnchoBanda=3;break;
			case 12:	AnchoBanda=1;break;
			case 13:	AnchoBanda=2;break;
			case 14:	AnchoBanda=3;break;
			case 15:	AnchoBanda=1;break;
			case 16:	AnchoBanda=2;break;
			case 17:	AnchoBanda=3;break;
			case 18:	AnchoBanda=1;break;
			case 19:	AnchoBanda=2;break;
			case 20:	AnchoBanda=3;break;
			case 21:	AnchoBanda=1;break;
			case 22:	AnchoBanda=2;break;
			case 23:	AnchoBanda=3;break;
			case 24:	AnchoBanda=1;break;
			case 25:	AnchoBanda=2;break;
			case 26:	AnchoBanda=3;break;
			}
			tiempoSimulacion = tSimulacion;
			AnchoBanda=AnchoBanda*muti;
			tiempoServicio=1/(AnchoBanda*10);	
			}
			}

	public void Await () {
		this.Resume();
		//modificado SimulationProcess.mainSuspend();
	}

}
